home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #1 / Amiga Plus CD - 2000 - No. 1.iso / Tools / Dev / Sas-PPC / samplelib1 / libinit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-03  |  11.4 KB  |  396 lines

  1. #define  _USEOLDEXEC_ 1
  2. #include <exec/types.h>
  3. #include <exec/nodes.h>
  4. #include <exec/memory.h>
  5. #include <exec/resident.h>
  6. #include <exec/libraries.h>
  7. #include <exec/execbase.h>
  8. #include <libraries/dos.h>
  9. #include <proto/exec.h>
  10. #include <proto/dos.h>
  11. #include <string.h>
  12. #include <dos/dostags.h>
  13. #include <PowerUP/PPCLib/Interface.h>
  14. #include <PowerUP/PPCLib/tasks.h>
  15. #include <PowerUP/PPCLib/ppc.h>
  16. #include <PowerUP/PPCLib/object.h>
  17. #include <PowerUP/PPCDisslib/PPCDiss.h>
  18. #include <PowerUP/pragmas/ppc_pragmas.h>
  19. #include <PowerUP/clib/ppc_protos.h>
  20. #include <PowerUP/pragmas/ppcdiss_pragmas.h>
  21. #include <PowerUP/clib/ppcdiss_protos.h>
  22.  
  23.  
  24. /* Prototypes */
  25. ULONG __asm _LibExpunge( register __a6 struct MyLibrary *libbase );
  26. ULONG __asm _LibInit   ( register __a0 APTR seglist,
  27.                          register __d0 struct MyLibrary *libbase );
  28.  
  29. int  __saveds __asm __UserLibInit   (register __a6 struct MyLibrary *libbase);
  30. void __saveds __asm __UserLibCleanup(register __a6 struct MyLibrary *libbase);
  31.  
  32. int  __saveds __asm __UserDevInit   (register __d0 long unit,
  33.                                      register __a0 struct IORequest *ior,
  34.                                      register __a6 struct MyLibrary *libbase);
  35. void __saveds __asm __UserDevCleanup(register __a0 struct IORequest *ior,
  36.                                      register __a6 struct MyLibrary *libbase);
  37.  
  38. int  __saveds __asm __libfpinit     (register __a6 struct MyLibrary *libbase);
  39. void __saveds __asm __libfpterm     (register __a6 struct MyLibrary *libbase);
  40. void __saveds __asm Set_ElfEntry    (register __a6 struct MyLibrary *libbase, 
  41.                                      register __d0 long value);
  42.  
  43. struct MyLibrary {
  44.         struct             Library ml_Lib;
  45.         ULONG              ml_SegList;
  46.         ULONG              ml_Flags;
  47.         APTR               ml_ExecBase; /* pointer to exec base  */
  48. #ifndef ONE_GLOBAL_SECTION
  49.         long *             ml_relocs;   /* pointer to relocs.    */
  50.         struct MyLibrary * ml_origbase; /* pointer to original library base  */
  51.         long               ml_numjmps;
  52. #endif
  53.         void *             ml_MyObject; /* pointer to ELF Object */
  54.         long               ml_ElfEntry; /* Entrypoint of Elf stub */
  55.  
  56. };
  57.  
  58. typedef LONG (*myPFL)();   /* pointer to function returning 32-bit int      */
  59.  
  60. /* library initialization table, used for AUTOINIT libraries                */
  61. struct InitTable {
  62.         ULONG        *it_DataSize;       /* library data space size         */
  63.         myPFL        *it_FuncTable;      /* table of entry points           */
  64.         APTR         it_DataInit;        /* table of data initializers      */
  65.         myPFL        it_InitFunc;        /* initialization function to run  */
  66. };
  67.  
  68. #ifndef ONE_GLOBAL_SECTION
  69. long _OSERR;
  70. long __base;
  71. #endif
  72.  
  73. /* symbols generated by blink */
  74. extern char __far _LibID[];             /* ID string                        */
  75. extern char __far _LibName[];           /* Name string                      */
  76. extern char __far RESLEN;               /* size of init data                */
  77. extern long __far NEWDATAL;             /* size of global data              */
  78. extern long __far NUMJMPS;              /* number of jmp vectors to copy    */
  79. extern myPFL _LibFuncTab[];             /* my function table                */
  80. extern long __far _LibVersion;          /* Version of library               */
  81. extern long __far _LibRevision;         /* Revision of library              */
  82.  
  83. long _StackPtr;
  84. long __stack;
  85. long __base;
  86. long _ONEXIT;
  87. struct WBStartup *_WBenchMsg;
  88. struct WBStartup *WBenchMsg;
  89.  
  90.  
  91. #define MYVERSION ((long)&_LibVersion)
  92. #define MYREVISION ((long)&_LibRevision)
  93. #define DATAWORDS ((long)&NEWDATAL)     /* magic to get right tpye of reloc */ 
  94. #define SIZEJMPTAB ((((long)libbase->ml_origbase->ml_numjmps)+3)&~3)
  95.                                         /* size in bytes of jmp table       */
  96.  
  97. /* From libent.o, needed to determine where data is loaded by loadseg       */
  98. extern long far _Libmergeddata; 
  99.  
  100. #define MYLIBRARYSIZE ((sizeof(struct MyLibrary) +3) & ~3)
  101.  
  102.  
  103.  
  104. struct InitTable __far _LibInitTab =  {
  105.         (long *)(&RESLEN+MYLIBRARYSIZE),
  106.         _LibFuncTab,
  107.         NULL,                        /* will initialize my own data */
  108.         _LibInit,
  109. };
  110.  
  111.  
  112. int _chkabort(void)
  113. {
  114.     return 0;
  115. }
  116.  
  117.  
  118. __asm ULONG _LibInit( register __a0 APTR seglist,
  119.                       register __d0 struct MyLibrary *libbase )
  120. {
  121. #ifdef ONE_GLOBAL_SECTION
  122.     long *reloc;
  123. #endif
  124.     long *sdata;
  125.     char *ddata;
  126.     long nrelocs;
  127.     struct TagItem MyTags[3];
  128.     extern __far long _ElfObject;
  129.     struct Library *PPCLibBase;
  130.  
  131.     libbase->ml_SegList = (ULONG) seglist;
  132.  
  133.     /* init. library structure (since I don't do automatic data init.) */
  134. #ifdef DEVICE
  135.     libbase->ml_Lib.lib_Node.ln_Type = NT_DEVICE;
  136. #else
  137.     libbase->ml_Lib.lib_Node.ln_Type = NT_LIBRARY;
  138. #endif
  139.     libbase->ml_Lib.lib_Node.ln_Name =  _LibName;
  140.     libbase->ml_Lib.lib_Flags = LIBF_SUMUSED | LIBF_CHANGED;
  141.     libbase->ml_Lib.lib_Version = MYVERSION;
  142.     libbase->ml_Lib.lib_Revision = MYREVISION;
  143.     libbase->ml_Lib.lib_IdString = (APTR) _LibID;
  144. #ifndef ONE_GLOBAL_SECTION
  145.     libbase->ml_relocs = NULL;
  146.     libbase->ml_origbase = libbase;
  147.     sdata = (long *)_LibInitTab.it_FuncTable;
  148.     libbase->ml_numjmps = (long)&NUMJMPS;
  149. #endif
  150.  
  151.     /* load the PPC ELF stub */
  152.     MyTags[0].ti_Tag = PPCELFLOADTAG_ELFADDRESS;
  153.     MyTags[0].ti_Data = (long)&_ElfObject;
  154.     MyTags[1].ti_Tag = PPCELFLOADTAG_ELFNAME;
  155.     MyTags[1].ti_Data = (long)_LibName;
  156.     MyTags[2].ti_Tag = TAG_DONE;
  157.  
  158.  
  159.     if ((PPCLibBase = OpenLibrary("ppc.library",0)) == NULL)
  160.        return NULL;
  161.  
  162.     if (libbase->ml_MyObject=PPCLoadObjectTagList(MyTags))
  163.     {
  164.         struct PPCObjectInfo MyInfo;
  165.  
  166.         MyInfo.Address   =        0;
  167.         MyInfo.Name      =        "__Entry";
  168.         MyTags[0].ti_Tag =        TAG_END;
  169.  
  170.         PPCGetObjectAttrs(libbase->ml_MyObject,
  171.                           &MyInfo,
  172.                           MyTags);
  173.         libbase->ml_ElfEntry = MyInfo.Address;
  174.         Set_ElfEntry(libbase, MyInfo.Address);
  175.         
  176.     }
  177.     else
  178.     {
  179.        CloseLibrary(PPCLibBase);
  180.        return NULL;
  181.     }
  182.     CloseLibrary(PPCLibBase);
  183.  
  184.  
  185.      /* Start of copy of global data after structure */
  186.     ddata = (char *)libbase + MYLIBRARYSIZE; 
  187.  
  188.     sdata = (long *)&_Libmergeddata; /* where loadseg loaded the data */
  189.     memcpy(ddata, (void *)sdata, DATAWORDS*4);
  190.  
  191.     /* perform relocs if we want one global section for all programs */
  192.     /* that have this lib open. If we want a global section for each */
  193.     /* open, copy the relocs, and do them on each open call.         */
  194.     sdata = sdata + DATAWORDS;
  195.     nrelocs = *sdata;
  196. #ifdef ONE_GLOBAL_SECTION
  197.     sdata++;
  198.     while (nrelocs > 0)
  199.     {
  200.        reloc = (long *)((long)ddata + *sdata++);
  201.        *reloc += (long)ddata;
  202.        nrelocs--;
  203.     }
  204.     
  205.     
  206. #ifndef DEVICE
  207.     if (__UserLibInit(libbase) != 0)
  208.        return NULL; /* abort if user init failed */
  209. #endif
  210.  
  211. #else
  212.     if (nrelocs) 
  213.     {
  214.       if ((libbase->ml_relocs = AllocMem((nrelocs * 4) + 4, MEMF_PUBLIC)) == NULL)
  215.         return 0;
  216.       memcpy((void *)libbase->ml_relocs, (void *)sdata, (nrelocs * 4) + 4);
  217.     }
  218. #endif
  219.  
  220.     return ( (ULONG) libbase );
  221. }
  222.  
  223. LONG __asm _LibOpen( 
  224. #ifdef DEVICE
  225.                      register __d0 long unit,
  226.                      register __a1 struct IORequest *ior,
  227. #endif
  228.                      register __a6 struct MyLibrary *libbase )
  229. {
  230. #ifndef ONE_GLOBAL_SECTION
  231.     struct MyLibrary *origbase = libbase;
  232.     struct ExecBase *SysBase = *(struct ExecBase **)4;
  233.     char *newlib;
  234.     long *sdata, *ddata, *reloc;
  235.     long nrelocs;
  236. #endif
  237.  
  238.     /* mark us as having another customer */
  239.     libbase->ml_Lib.lib_OpenCnt++;
  240.  
  241.     /* clear delayed expunges (standard procedure) */
  242.     libbase->ml_Lib.lib_Flags &= ~LIBF_DELEXP;
  243.  
  244. #ifndef ONE_GLOBAL_SECTION
  245.     /* Allocate new lib base */
  246.     newlib = AllocMem((long)(MYLIBRARYSIZE + 
  247.                              ((long)&RESLEN) + SIZEJMPTAB), 
  248.                              MEMF_PUBLIC|MEMF_CLEAR);
  249.  
  250.     if (newlib == NULL) goto error;
  251.         
  252.     /* copy over data */
  253.     memcpy(newlib, (char *)libbase - SIZEJMPTAB, 
  254.            (long)(MYLIBRARYSIZE + DATAWORDS*4 + SIZEJMPTAB));
  255.     
  256.     libbase = (struct MyLibrary *)(newlib+SIZEJMPTAB);
  257.     libbase->ml_relocs = NULL;
  258.     
  259.     /* perform relocs */       
  260.     ddata = (long *)((char *)libbase + MYLIBRARYSIZE); 
  261.     sdata = libbase->ml_origbase->ml_relocs;
  262.     if (sdata)
  263.     {
  264.        nrelocs = *sdata++;
  265.        while (nrelocs > 0)
  266.        {
  267.           reloc = (long *)((long)ddata + *sdata++);
  268.           *reloc += (long)ddata;
  269.           nrelocs--;
  270.        }
  271.     }
  272.  
  273.  
  274.     Set_ElfEntry(libbase, libbase->ml_ElfEntry);
  275.         
  276.  
  277.     /* now we need to flush the cache because we copied the jmp table */
  278.     if (SysBase->LibNode.lib_Version >= 36) 
  279.       CacheClearU();
  280.  
  281. #ifdef DEVICE
  282.     ior->io_Device = (struct Device *)libbase; /* local copy of libary base */
  283. #endif
  284.  
  285.     if (__libfpinit(libbase) || 
  286. #ifdef DEVICE
  287.         __UserDevInit(unit, ior, libbase) != 0
  288. #else
  289.         __UserLibInit(libbase) != 0
  290. #endif
  291.        )
  292.     {
  293.        __libfpterm(libbase);
  294.        FreeMem(newlib, (long)(MYLIBRARYSIZE + 
  295.                        ((long)&RESLEN) + SIZEJMPTAB));
  296. error:
  297.        origbase->ml_origbase->ml_Lib.lib_OpenCnt--;
  298.        return NULL; /* abort if user init failed */
  299.     }
  300.  
  301. #else
  302. #ifdef DEVICE
  303.     if (__UserDevInit(unit, ior, libbase) != 0)
  304.     {
  305.         libbase->ml_Lib.lib_OpenCnt--;
  306.         return NULL;
  307.     }    
  308. #endif
  309. #endif
  310.  
  311.     return ( (LONG) libbase );
  312. }
  313.  
  314. ULONG __asm _LibClose( 
  315. #ifdef DEVICE
  316.                        register __a1 struct IORequest *ior,
  317. #endif                       
  318.                        register __a6 struct MyLibrary *libbase )
  319. {
  320.     ULONG retval = 0;
  321.     
  322. #ifndef ONE_GLOBAL_SECTION
  323.     struct MyLibrary *origbase;
  324.  
  325.     if (libbase != libbase->ml_origbase)
  326.     {
  327. #ifdef DEVICE
  328.        __UserDevCleanup(ior, libbase);
  329. #else
  330.        __UserLibCleanup(libbase);
  331. #endif
  332.        __libfpterm(libbase);
  333.        origbase = libbase->ml_origbase;
  334.        FreeMem((char *)libbase-SIZEJMPTAB, 
  335.                (long)(MYLIBRARYSIZE + ((long)&RESLEN)+SIZEJMPTAB));
  336.        libbase = origbase;
  337.     }
  338. #else
  339. #ifdef DEVICE
  340.     __UserDevCleanup(ior, libbase);
  341. #endif
  342. #endif
  343.  
  344.     if (( --libbase->ml_Lib.lib_OpenCnt == 0 ) &&
  345.                         ( libbase->ml_Lib.lib_Flags & LIBF_DELEXP ))
  346.     {
  347.         /* no more people have me open,
  348.          * and I have a delayed expunge pending
  349.          */
  350.          retval = _LibExpunge( libbase ); /* return segment list        */
  351.     }
  352.  
  353.     return (retval);
  354. }
  355.  
  356. ULONG __asm _LibExpunge( register __a6 struct MyLibrary *libbase )
  357. {
  358.     ULONG seglist = 0;
  359.     LONG  libsize;
  360.     struct Library *PPCLibBase;
  361.  
  362. #ifndef ONE_GLOBAL_SECTION
  363.     libbase = libbase->ml_origbase;
  364. #endif
  365.  
  366.     libbase->ml_Lib.lib_Flags |= LIBF_DELEXP;
  367.     if ( libbase->ml_Lib.lib_OpenCnt == 0 )
  368.     {
  369.         /* really expunge: remove libbase and freemem        */
  370. #ifndef ONE_GLOBAL_SECTION
  371.         if (libbase->ml_relocs)
  372.            FreeMem(libbase->ml_relocs, (*libbase->ml_relocs * 4) + 4);
  373. #else
  374.         __UserLibCleanup(libbase);
  375. #endif
  376.  
  377.         if (PPCLibBase = OpenLibrary("ppc.library",0))
  378.         {
  379.            PPCUnLoadObject(libbase->ml_MyObject);
  380.            CloseLibrary(PPCLibBase);
  381.         }
  382.         
  383.         seglist = libbase->ml_SegList;
  384.  
  385.         Remove( (struct Node *) libbase);
  386.  
  387.         libsize = libbase->ml_Lib.lib_NegSize + libbase->ml_Lib.lib_PosSize;
  388.         FreeMem( (char *) libbase - libbase->ml_Lib.lib_NegSize,(LONG) libsize );
  389.     }
  390.  
  391.     /* return NULL or real seglist                                */
  392.     return ( (ULONG) seglist );
  393. }
  394.  
  395.  
  396.